package cn.bobohost.crmrbac.config;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    /**
     * 安全数据
     * @return
     */
    @Bean
    public Realm realm() {
     /*  // 使用文本配置实现Realm---做测试使用
        TextConfigurationRealm realm = new TextConfigurationRealm();
        // 设置用户：帐号=密码,角色
        realm.setUserDefinitions("rose=123456,user\n" + "admin=1,admin");

        realm.setRoleDefinitions("admin=read,write\n" + "user=read");
        // 启用缓存
//        realm.setCachingEnabled(true);
        return realm;*/
        //自己new一个对象，交给spring容器管理，成为bean
//        return new MyRealm();



        MyRealm myRealm = new MyRealm();
        myRealm.setCredentialsMatcher(hashedCredentialsMatcher());

        // 设置缓存管理器
        myRealm.setCacheManager(cacheManager());

        // 全局缓存开关
//        myRealm.setCachingEnabled(true);
        //启用认证缓存
//        myRealm.setAuthenticationCachingEnabled(true);
        //默认缓存名称：authenticationCache
        myRealm.setAuthenticationCacheName("authenticationCache");
        //启用授权缓存
//        myRealm.setAuthorizationCachingEnabled(true);
        //默认缓存名称：authorizationCache
        myRealm.setAuthorizationCacheName("authorizationCache");

        return myRealm;
    }

    /**
     * 缓存管理器
     * @return
     */
    @Bean
    public CacheManager cacheManager() {
        // 使用Shiro自带的内存缓存
//        return new MemoryConstrainedCacheManager();


        EhCacheManager cacheManager = new EhCacheManager();
        cacheManager.setCacheManagerConfigFile("classpath:config/ehcache-shiro.xml");
        return cacheManager;
    }


    /**
     * 密码加密算法匹配器
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName(Sha256Hash.ALGORITHM_NAME);
        hashedCredentialsMatcher.setHashIterations(1024);
        //没有盐
        return hashedCredentialsMatcher;
    }

    /**
     * 配置过滤规则
     * @return
     */
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition() {
        DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();

        /*
         * anon:无需认证就可以访问
         * authc：必须认证了才能访问
         * role:必须拥有某个角色才能访问
         * perms:必须拥有某个权限才能访问
         *
         * 通配符：
            	*：0或n个字符
            	?:一个字符
            	**:0或n个路径下的0或n个字符，即任意路径或子路径下的任意字符。
         * */

        // logged in users with the 'admin' role
        chainDefinition.addPathDefinition("/admin/**", "authc, roles[admin]");

        // logged in users with the 'document:read' permission
        chainDefinition.addPathDefinition("/docs/**", "authc, perms[document:read]");



        //需要某个角色
        //员工管理列表--需要  人事管理（HR_MGR）的角色
        chainDefinition.addPathDefinition("/employee/list","roles[HR_MGR]");
        //需要某个权限才可以---
        chainDefinition.addPathDefinition("/employee/input","perms[customer:potentialList]");


        //-----登录注册相关的都要是匿名访问--不加权限
        //配置登录页面为匿名访问
//        chainDefinition.addPathDefinition("/login.html", "anon");

        //定义要放行的map
        Map<String,String> map = new HashMap();
        //排除掉静态资源
        map.put("*.css","anon");
        map.put("*.js","anon");
        map.put("/css/**","anon");
        map.put("/img/**","anon");
        map.put("/js/**","anon");
        map.put("/login.html*","anon");//登录页面放行，防止/login.html?xxx=xxx
        map.put("/user/login*","anon"); //注意登录操作要放行  /user/login/a/b

        map.put("/a.html","anon");

        //加入到过滤器链规则中
        chainDefinition.addPathDefinitions(map);

        // all other paths require a logged in user
        chainDefinition.addPathDefinition("/**", "authc");
        return chainDefinition;
    }




}
